﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Deer;
using Deer.Log;
using Deer.Util;

namespace Telex;

sealed class RpcClient : ARpcService, IRpcClient
{
    public RpcClient(ILogger logger, SslClientConfig sslClientConfig, string secretkey, ProtocolMap protocolMap, ActionAsync<RpcHost, ServiceKind> channelActiveFunc, ActionAsync<RpcHost, ServiceKind> channelInactiveFunc)
        : base(logger, protocolMap, channelActiveFunc, channelInactiveFunc)
    {
        this.secretkey = secretkey;
        this.sslClientConfig = sslClientConfig;
    }
    
    private string secretkey;
    private SslClientConfig sslClientConfig;

    private  List<TcpClient> clientArr = new List<TcpClient>();

    protected override ServiceKind CurrentKind
    {
        get { return ServiceKind.CLIENT; }
    }
    
    public ValueTask<RpcHost> ConnectAsync(IPEndPoint point, int count, RpcHost host)
    {
        if (host.IsEmpty())
        {
            throw new ArgumentNullException(nameof(host));
        }

        if (point == null)
        {
            throw new ArgumentNullException(nameof(point));
        }
        
        if (count > 20 || count < 1) count = 20;
        
        var taskArr = new Task<RpcHost>[count];
        for (int i = 0; i < count; i++)
        {
            var client = new TcpClient(sslClientConfig, this.secretkey, host);
            client.OnConnect += OnConnectEvent;
            client.OnDisconnect += OnDisconnectEvent;
            taskArr[i] = client.ConnectAsync(point).AsTask();
            clientArr.Add(client);
        }
        
        Task.WaitAll(taskArr);
        return ValueTaskUtil.FromResult(taskArr[0].Result);
    }

    

    public override async ValueTask StopAsync()
    {
        foreach (var client in clientArr)
        {
            await client.StopAsync();
        }
        this.clientArr.Clear();
        
        await base.StopAsync();
    }
}